package cn.example.util.toolkit;


import cn.example.project1.vo.TreeData;
import cn.example.util.ToolFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * Tree工具类
 * Created by WuYubin on 2016/12/28.
 */
public class ListUtil {

    private static final Logger log = LoggerFactory.getLogger(ListUtil.class);

    private static class SingletonHolder {
        private static final ListUtil INSTANCE = new ListUtil();
    }

    private ListUtil() {
    }

    public static ListUtil getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 获得List最后一个对象
     *
     * @param list List
     * @param <T>  List泛型
     * @return T
     */
    public <T> T getLastObj(List<T> list) {
        if (!ToolFactory.getNullUtil().isNull(list)) {
            return list.get(list.size() - 1);
        }
        return null;
    }

    /**
     * 合并List，去除重复对象
     *
     * @param lists 待合并去重List
     * @param <T>   List泛型
     * @return ArrayList<T>
     */
    @SafeVarargs
    public final <T> ArrayList<T> mergeList(List<T>... lists) {
        NullUtil nullUtil = ToolFactory.getNullUtil();
        if (!nullUtil.isNull(lists)) {
            Set<T> set = new HashSet<>();
            for (List<T> l : lists) {
                if (!nullUtil.isNull(l)) {
                    set.addAll(removeNull(l));
                }
            }
            return new ArrayList<>(set);
        }
        return new ArrayList<>();
    }

    /**
     * 合并List，只保留都有的对象（交集）
     *
     * @param lists 待合并List集合
     * @param <T>   List泛型
     * @return List<T>
     */
    public <T> List<T> intersectList(List<List<T>> lists) {
        Optional<List<T>> result = lists.parallelStream()
                .filter(elementList -> elementList != null && (elementList).size() != 0)
                .reduce((a, b) -> {
                    a.retainAll(b);
                    return a;
                });
        return result.orElse(new ArrayList<>());
    }

    /**
     * List去除null元素
     *
     * @param list 待去除null的集合
     * @param <T>  List泛型
     * @return List
     */
    public <T> List<T> removeNull(List<T> list) {
        list.removeAll(Collections.singleton((T) null));
        return list;
    }

    /**
     * List转换为Tree
     *
     * @param temp   List<TreeData>所有
     * @param parent List<TreeData>顶级父
     * @return List<TreeData>
     */
    public List<TreeData> list2Tree(List<TreeData> temp, List<TreeData> parent) {
        temp.removeAll(parent);
        for (TreeData cParent : parent) {
            treeData(cParent, temp);
        }
        return parent;
    }

    private void treeData(TreeData parent, List<TreeData> temp) {
        if (ToolFactory.getNullUtil().isNull(temp)) {
            return;
        }
        List<TreeData> children = new ArrayList<>();
        for (TreeData c : temp) {
            if (c.getParentId().equalsIgnoreCase(parent.getId())) {
                children.add(c);
            }
        }
        if (!ToolFactory.getNullUtil().isNull(children)) {
            parent.setNodes(children);
            List<TreeData> tempChild = new ArrayList<>(temp);
            tempChild.removeAll(children);
            for (TreeData p : children) {
                treeData(p, tempChild);
            }
        }
    }
}
